
function debuff_filter(j, prev_spell)
	local predict_offset = 0;
	if (prev_spell) then
		predict_offset = prev_spell["casttime"]
	end
	local a = "PLAYER"
	if j["anysource"] then
		a = nil;
	end
	if (j["debuffid"] == nil or (((({UnitDebuff("target", GetSpellInfo(j["debuffid"]), nil, a)})[7]) or 0 )- GetTime() < j["ticktime"]  + (predict_offset or 0)))  then
		return true
	end
	if (j["debuffstacks"]) then
		if (j["debuffstacks"] > (({UnitDebuff("target", GetSpellInfo(j["debuffid"]), nil, a)})[4])) then
			return true
		end
	end
	return false
end

function resource_filter(j, prev_spell)
	local resource = UnitPower("player")
	local _, acReg = GetPowerRegen()
	local predict_offset = 0;
	if (prev_spell) then
		predict_offset = prev_spell["casttime"]
		resource = (resource - (prev_spell["resource"] or 0))+(acReg*predict_offset)
	end
	if (resource >= (j["resource"] or 0 ))then
		return true
	end
	return false
end

function selfbuff_filter(j, prev_spell)
	if (not j["selfbuff"]) then return true; end
	local predict_offset = 0;
	local nev = 0
	local count = ({UnitBuff("player", GetSpellInfo(j["selfbuff"].id))})[4]
	if (prev_spell) then
		predict_offset = prev_spell["casttime"]
		if (prev_spell.selfbuff) then
			if (prev_spell.selfbuff.id) then
				if (prev_spell.selfbuff.id == j["selfbuff"].id) then
					nev = nev + (prev_spell.selfbuff.devourse or 0)
				end
			end
		end
		if prev_spell.newbuff == j["selfbuff"].id then
			count = 1
		end
	end
	
	if (count ~= nil) then
		if (count - nev >=  j["selfbuff"].count) then
			return true; 
		end
		if ((({UnitBuff("player", GetSpellInfo(j["selfbuff"].id))})[7]) - GetTime() <= predict_offset) then
			return true; 
		end
	end 
	return false
end

function notselfbuff_filter(j, prev_spell)
	if (not j["notselfbuff"]) then return true; end
  	local predict_offset = 0;
	local count = ({UnitBuff("player", GetSpellInfo(j["notselfbuff"].id))})[4]
	if (prev_spell) then
		predict_offset = prev_spell["casttime"]
		if j["selfbuff"] and prev_spell.newbuff then
			if prev_spell.newbuff == (j["selfbuff"].id) then
				count = 1
			end
		end
	end
	if (count ~= nil) then
		if ( count >= j["notselfbuff"].count) then
			return false; 
		end
		if ((({UnitBuff("player", GetSpellInfo(j["notselfbuff"].id))})[7]) - GetTime() <=  predict_offset) then
			return false; 
		end
	end
	return true
end

function selfdebuff_filter(j, prev_spell)
	if (not j["selfdebuff"]) then return true; end
    local predict_offset = 0;
	local count = ({UnitDebuff("player", GetSpellInfo(j["selfdebuff"].id))})[4]
	if (prev_spell) then
		predict_offset = prev_spell["casttime"]
		if prev_spell.newdebuff == j["selfdebuff"].id then
			count = 1
		end
	end
	if (count ~= nil) then
		if (count >= j["selfdebuff"].count) then
			return true; 
		end
		if ((({UnitDebuff("player", GetSpellInfo(j["selfdebuff"].id))})[7]) - GetTime() <=  predict_offset) then
			return true; 
		end
	end 
	return false
end

function notselfdebuff_filter(j, prev_spell)
	if (not j["notselfdebuff"]) then return true; end
    local predict_offset = 0;
	local count = nilsafenumber(({UnitDebuff("player", GetSpellInfo(j["notselfdebuff"].id))})[4])
	if (prev_spell) then
		predict_offset = prev_spell["casttime"]
		if prev_spell.newdebuff == j["notselfdebuff"].id then
			count = count + 1
		end
	end
	if (count >= j["notselfdebuff"].count) then
	--	print("count")
		return false; 
	end
	--[[	if (nilsafenumber(({UnitDebuff("player", GetSpellInfo(j["notselfdebuff"].id))})[7]) - GetTime() <=  predict_offset) then
			print("ka")
			return false; 
		end]]
	return true
end

function targetdebuff_filter(j, prev_spell)
	if (not j["targetdebuff"]) then return true; end
    local predict_offset = 0;
	if (prev_spell) then
		predict_offset = prev_spell["casttime"]
	end
	if (UnitDebuff("target", GetSpellInfo(j["targetdebuff"].id), nil, "PLAYER")) then
		if ((({UnitDebuff("target", GetSpellInfo(j["targetdebuff"].id), nil, "PLAYER")})[4]) >= j["targetdebuff"].count) then
			return true; 
		end
		if ((({UnitDebuff("target", GetSpellInfo(j["targetdebuff"].id))})[7]) - GetTime() <=  predict_offset) then
			return true; 
		end
	end
	return false
end

function nottargetdefbuff_filter(j, prev_spell)
	if (not j["nottargetdefbuff"]) then return true; end
    local predict_offset = 0;
	if (prev_spell) then
		predict_offset = prev_spell["casttime"]
	end
	if (UnitDebuff("target", GetSpellInfo(j["nottargetdefbuff"].id), nil, "PLAYER"))  then
		if ((({UnitDebuff("target", GetSpellInfo(j["nottargetdefbuff"].id))})[4]) >=  j["nottargetdefbuff"].count) then
			return false; 
		end
		if ((({UnitDebuff("target", GetSpellInfo(j["nottargetdefbuff"].id))})[7]) - GetTime() <=  predict_offset) then
			return false; 
		end
	end
	return true
end


function double_filter(j, prev_spell)
	if (prev_spell==nil or prev_spell["id"] ~= j["id"] or (j["debuffid"] == nil and j["cd"] == 0)) then
		if (j["selfbuff"] and j["selfbuff"]["proc"] and prev_spell and prev_spell["id"]  == j["id"] ) then return false; end
		return true
	end
	if (j["debuffid"] == nil and ((prev_spell["cd"] or 0) <= (prev_spell["casttime"] or 0)) ) then
		if (j["selfbuff"] and j["selfbuff"]["proc"] and prev_spell and prev_spell["id"]  == j["id"] ) then return false; end
		return true;
	end
	return false;
end

function cd_filter(j, prev_spell)
	local predict_offset = 0;
	if (prev_spell) then
		predict_offset = prev_spell["casttime"]
	end
	local gcd = 0
	if (facerollgcdcheck[faceroll_profile]) then
		gcd = ( ({GetSpellCooldown(facerollgcdcheck[faceroll_profile])})[2]  or 0)
	end
	if (not j["cd"] or j["cd"] == 0 or (({GetSpellCooldown(j["id"])})[1] + ({GetSpellCooldown(j["id"])})[2] - GetTime()) <= predict_offset + gcd)  then
		return true
	end
	return false
end

function power_filter(j, prev_spell)
	if (not j["power"]) then return true; end
	local predict_offset
	local _, acReg = GetPowerRegen()
	local m = UnitPower("player");
	if prev_spell then
		predict_offset = prev_spell["casttime"]
		m = (m - (prev_spell["resource"] or 0))+(acReg*predict_offset)
	end
	local mm = maxmana;
	local p = m / mm * 100
--	print(p.."="..m.."/"..mm.."*100")
	if p > 100 then
		p = 100
	end
	if (j["power"].minp > p) then return false; end
	if (j["power"].maxp < p) then return false; end
	return true
end


function interrupt_filter(j, prev_spell)
	if (not j["onlytointerrupt"]) then return true; end
	if (prev_spell) then
		if (prev_spell["onlytointerrupt"]) then return false; end
	end
	local name, _, _,_, _, _, _, _, notInterruptible = UnitCastingInfo("target")
	if (not name) then return false; end
	if (notInterruptible) then return false; end
	return true;	
end

function combo_filter(j, prev_spell)

	if (not j["combopoints"]) then return true; end

	local cp = GetComboPoints("player", "target");
	if (prev_spell ~= nil) then 
		cp = cp - (prev_spell["combopoints"] or 0);
		if (cp < 0)then
			cp = 0;
		end
	end
	if ((cp-j["combopoints"])>=0)then
		return true
	else
		return false
	end
end
